/*
 * Copyright 2007-2008 Andrew O'Malley
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


package ws.quokka.plugin.javacc;

import org.apache.tools.ant.taskdefs.Java;
import org.apache.tools.ant.taskdefs.UpToDate;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.util.ScriptRunnerBase;
import org.apache.tools.ant.util.ScriptRunnerHelper;

import ws.quokka.core.plugin_spi.support.AbstractPlugin;
import ws.quokka.core.plugin_spi.support.Setter;
import ws.quokka.core.plugin_spi.support.TypedProperties;

import ws.quokka.plugin.lifecycle.LifeCycleImpl;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StringReader;


/**
 *
 */
public class JavaccPlugin extends LifeCycleImpl {
    //~ Methods --------------------------------------------------------------------------------------------------------

    public void javaccMain() {
        javacc();
    }

    public void javaccTest() {
        javacc();
    }

    public void javacc() {
        File out = properties().getFile("out");
        File in = properties().getFile("in");

        // Check if we're up to date
        UpToDate upToDate = new UpToDate();
        upToDate.setProject(getProject());
        upToDate.setTargetFile(in);
        upToDate.addSrcfiles(utils().toFileSet(out));

        if (out.exists() && !upToDate.eval() && (out.list().length != 0)) {
            log().verbose("Skipping javacc as the generated sources are up to date");

            return;
        }

        utils().mkdir(out);

        File sourcesRoot = properties().getFile("sourcesRoot");
        String sourcesPath = properties().getString("sourcesPath");
        assertTrue(sourcesPath.equals("main") || sourcesPath.equals("test"),
            "'sourcesPath' must be either 'main' or 'test' for compilation in 'compile' or 'test-compile' respectively");

        String jdkVersion = properties().getString("jdkVersion", null);
        String options = properties().getString("options", null);

        Java javacc = (Java)utils().init(new Java(), "javacc");
        javacc.setClassname("javacc");

        if (options != null) {
            javacc.createArg().setLine(options);
        }

        if (jdkVersion != null) {
            javacc.createArg().setValue("-JDK_VERSION=" + jdkVersion);
        }

        javacc.createArg().setValue("-OUTPUT_DIRECTORY=" + out.getPath());
        javacc.createArg().setValue(in.getPath());
        javacc.setFailonerror(true);
        javacc.setFork(false);
        javacc.setClasspath(getResources().getPathGroupAsPath("classpath"));
        javacc.perform();

        // Add the generated sources
        Path sources = new Path(getProject(), sourcesRoot.getPath());

        if (sourcesPath.equals("main")) {
            getLifeCycle().getState().addGeneratedSources(sources);
        } else {
            getLifeCycle().getState().addGeneratedTestSources(sources);
        }
    }
}
